package juc2.synchronizeddome;


import org.openjdk.jol.info.ClassLayout; //测试对象头工具

/**
 * 对象头与锁的变化
 */


public class JDK17ObjectHeaderDemo {
    public static void main(String[] args) throws InterruptedException {
        // JDK 17中偏向锁默认关闭，若需测试需添加JVM参数：+UseBiasedLocking：强制开启偏向锁（JDK 17 中需显式开启）。
        //BiasedLockingStartupDelay=0：关闭偏向锁的启动延迟（默认延迟 4 秒，避免等待）。
        // -XX:+UnlockDiagnosticVMOptions -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0
        // 测试用的锁对象
        Object lock = new Object();//lock 对象是同步的核心，JVM 会为这个 lock 对象隐式关联一个 Monitor

        // 1. 无锁状态
        System.out.println("=== 1. 无锁状态 ===");
        // 打印对象内存布局（包含对象头）
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        Thread.sleep(1000);

        // 2. 轻量级锁（单线程持有）
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("\n=== 2. 轻量级锁（线程t1持有） ===");
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                try {
                    // 持有锁一段时间，便于观察
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1");
        t1.start();
        t1.join(); // 等待t1执行完毕

        // 3. 重量级锁（多线程竞争）
        System.out.println("\n=== 3. 重量级锁（多线程竞争中） ===");
        Runnable heavyTask = () -> {
            synchronized (lock) {
                try {
                    // 延长持有时间，确保触发重量级锁
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread t2 = new Thread(heavyTask, "t2");
        Thread t3 = new Thread(heavyTask, "t3");
        t2.start();
        t3.start();
        // 等待t2和t3启动并获取锁（此时处于重量级锁状态）
        Thread.sleep(500);
        // 打印重量级锁状态的对象头
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());

        // 等待所有线程结束
        t2.join();
        t3.join();

        // 4. 锁释放后（回到无锁状态）
        System.out.println("\n=== 4. 锁释放后（无锁状态） ===");
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }
}

